public class OutClass {
    //内部类和外部类共用同一个Java源文件
    //但是经过编译之后，内部类会形成单独的字节码文件
    //
    //内部类的分类
    //

    //成员位置定义：没有被static修饰-》实例内部类
    //
    private int a;
    static int b;//静态
    int c;
    public void methodA(){
        a=10;
        System.out.println(a);
    }
    public static void methodB(){
        System.out.println(b);
    }


    //静态内部类
    public static class InnerClass3{
        public void methodInner(){
//            a=100;
            //编译失败，因为a不是类成员变量

            b=200;
//            methodA();
            //编译失败，因为methodB（）不是类成员方法
            //
        methodB();
        }

    }



    public static void main3(String[] args) {
        //你是直接在外部类所在的地方去调用
        //

        //在静态内部类中只能访问外部类中的静态成员
        //创建静态内部类的时候 ，不需要先创建外部类对象

        OutClass.InnerClass3 innerClass3 =new OutClass.InnerClass3();
        innerClass3.methodInner();
    }
    public class InnerClass1{
        int c;
        public void methodInner(){
            a=100;
            b=200;
            //在内部类中可以直接访问外部类
            //任意访问限定修饰符的成员
            //因为最小的都可以访问
            //本来就在同一个类中（也在同一个包）
            //
            methodA();
            methodB();

            //如果外部类和实例内部类中具有同名的成员，优先访问的是内部类自己的
            //
            c=300;
            System.out.println(c);

            //如果重名还非要访问外部类同名成员，必须要
            //外部类.this.同名成员名字
            //
            OutClass.this.c=4000;
            System.out.println(OutClass.this.c);
        }



    }

    public static void main2(String[] args) {
        //外部类：对象的创建以及成员的访问
        //
        OutClass outClass=new OutClass();
        System.out.println(outClass.a);
        System.out.println(OutClass.b);
        System.out.println(outClass.c);
        outClass.methodA();
        //outClass.methodB();
        OutClass.methodB();//更推荐使用这个
        //

        //
        System.out.println("=========实例内部类的访问========");
        //要访问实力内部类中的成员，必须要创建实例内部类对象
        //而实例内部类定义与外部类成员定义位置相同，因此创建实例内部类对象必须借助于外部类
        //

        //创建实例内部类对象
        OutClass.InnerClass1 innerClass1 = new OutClass().new InnerClass1();

        OutClass.InnerClass1 innerClass2=outClass.new InnerClass1();
        innerClass2.methodInner();

        //1.外部类中的任何成员都可以在实例内部类方法中直接访问--甚至没有权限限制，因为在同一个包的同一个 类中了
        //2.实力内部类所处的位置与外部类成员位置相同，可以想象为一种特殊的成员，因此也受public、private等访问限定修饰符的影响
        //3.在实例内部类方法中访问同名成员时候，优先访问自己的，如果要访问外部类同名成员，必须：
        //外部类名称.this.同名成员   访问
        //4.实例内部类对象，必须要现有外部类对象前提下才能创建
        //5.实例内部类的非静态方法中包含了一个指向外部类对象的引用
        //6.外部类中，不能直接访问实例内部类中的成员，如果要访问，必须要先创建内部类对象
        //



        //静态内部类
        //---被static修饰的内部成员类

    }

    //
    //被static修饰的，-》静态内部类
    static class InnerClass2{

    }

    //根据内部类定义的位置不同，一般可以分为一下几种形式
    //1.成员内部类：（普通内部类：未被static修饰的成员内部类和静态内部类：被static修饰的成员内部类）
    //2.局部内部类：（不谈修饰符）
    public void method(){
        //方法中定义的内部类--局部内部类---几乎不用
        //
        //
        class InnerClass3{
            //也可以在这里定义内部类，但是基本上不用
            //
        }
        //局部内部类：不谈修饰符
        //匿名内部类
        //

        //实例内部类---没有被static修饰的成员内部类
        //
    }
}

//上面这个类和下面这个类是两个独立的类
//没有啥子联系
//
class NOtInnerClass{
    //这个不是内部类
    //在同一个文件里面，也不能称为
    //
}
